package QAInfo::DataSource::EmailReports;

sub new {
    my ($class, $message) = @_;
    if ( !$message ) {
        warn "Variable \$message is empty at ".caller(0)."\n";
        return undef;
    }
    
    my $parsed = new QAInfo::DataSource::EmailReports::MIMEParser($message);
    my $this = {
                    parsed     => $parsed,
                    last_error => "", 
               };
    bless $this, $class
}
=pod
last_error - returns last error message
=cut
sub last_error { shift->{last_error} }

sub trim_str { 
    my $str = shift;
    $str =~ s/^\s*(.+?)\s*$/$1/s;
    return $str;
}

=pod
sub parse - parses the message and returns following structure:
 {
    head_date       => undef,
    head_subj       => undef,
    body            => undef,
    
    test_plan_name  => undef,
    version         => undef, 
    language        => undef,
    verdict         => undef,
    edition_name    => undef,
    edition_protect => undef,
    edition_type    => undef,
    edition_media   => undef,
    computer_name   => undef,
    sender_name     => undef,

    os_info         => undef,
    statistics      => undef,
    links           => undef,
    comments        => undef,
    upgrade_id      => undef,
 };

=cut
sub parse {
    my ($this) = @_;
    my $parsed = $this->{parsed};

    my $result = undef;

    my $str_body      = $parsed->body;
    my $data_datetime = $parsed->get('Date');
    my $data_subject  = $parsed->get('Subject');

    # Parse message body
    my $DATE_RE    = qr{\d\d/\d\d/\d\d\b};
    my $PLAN_RE    = qr{[^\t]+};
    my $VERDICT_RE = qr{[^\t]+};
    my $LNG_RE     = qr{[^\t][^\t][^\t]};
    my $VERSION_RE = qr{\d?\d\.\d\d\.\d\d\d\.\d\d\d};
    my $EDITION_RE = qr{[^\t]+};
    my $VARIANT_RE = qr{[^\t]+};
    my $PATH_RE    = qr{[^\t]+};
    my $EXCEPT_RE  = qr{[^\t]+};
    my $PC_RE      = qr{[^\t]+};
    my $SENDER_RE  = qr{[^\t]+};

    # First try to get information. 
    # First string with required report data supported in newer
    # versions of report format
    my ( $tp_name, $verdict, $lang, $ver, $ed, $comp, $sender, $media );
    my ( $os_info, $statistics, $links, $comments, $upgrade_id );

    if ($str_body =~ m/^$DATE_RE\t($PLAN_RE)\t($VERDICT_RE)\t($LNG_RE)\t
                        ($VERSION_RE)\t($EDITION_RE)\t(?:$VARIANT_RE)\t
                        (?:$PATH_RE)\t(?:$EXCEPT_RE)?\t($PC_RE)\t($SENDER_RE)\t/xm)
    {
        my ( $tp_name, $verdict, $lang, $ver, $ed, $comp, $sender, $media ) = 
           ( $1, $2, $3, $4, $5, $6, $7 );

        $verdict =~ s/_Vista//i;

        if ( $ed =~ /^(\S+?)(?:_(CopyProtection))?\.([^_]+)(?:_(\S+))?/ ) {
            ($edition, $protection, $build_type, $media) = ($1, $2, $3, $4);
        }
        
        if ( !defined $media 
             && $data_subject =~ /$edition(?:[_]$protection)?[\.]$build_type[_]([^\s_]+)/) 
        {
            $media = $1; 
        }

        # Get OS info, test statistics, result links
        # QAA comments, upgrade id

        # OS info:
        my $OS_BEGIN = 'OS version:';
        if ( $str_body =~ m/$OS_BEGIN\s*(.*?)\s*\n/is ) {
            $os_info = $1; 
        }
        
        # Test statistics:
        my $STAT_BEGIN  = 'Final results:';
        my $WORD_TOTALS = 'Totals:';
        if ( $str_body =~ m/($STAT_BEGIN.*$WORD_TOTALS.*?)\n/is ) {
            $statistics = $1;
        }

        # Links
        my $LINKS_BEGIN = "You can find all logs and result files in :";
        my $LINKS_END   = 'Summary of the last';
        if ( $str_body =~ m/$LINKS_BEGIN(.*?)$LINKS_END/is ) {
            $links = trim_str $1;
        }

        # QAA comments
        my $QAACOM_BEGIN = "QAA comments:";
        my $QAACOM_END   = $LINKS_BEGIN;

        if ( $str_body =~ m/$QAACOM_BEGIN(.*?)$QAACOM_END/is ) {
            $comments = trim_str $1;
        }

        # Upgrade ID
        $UPGRD_INFO_START = 'Upgrade info:';
        $ID = 'ID';
        if ( $str_body =~ m/$UPGRD_INFO_START.+?$ID([A-Za-z0-9_-]+?)\s/s ) {
            $upgrade_id = $1;
        }


        $result = {
                     head_date       => $data_datetime,
                     head_subj       => $data_subject,
                     body            => $str_body,

                     test_plan_name  => $tp_name,
                     verdict         => $verdict,
                     language        => $lang,
                     version         => $ver, 
                     edition_name    => $edition,
                     edition_protect => $protection,
                     edition_type    => $build_type,
                     edition_media   => $media,
                     computer_name   => $comp,
                     sender_name     => $sender,
                     os_info         => $os_info,
                     statistics      => $statistics,
                     links           => $links,
                     comments        => $comments,
                     upgrade_id      => $upgrade_id,
                  };
    }
    else {
        $this->{last_error} = "Report not supported: $data_subject\t\t$mail_date\t\t$tp_name\n";
    }

    return $result;
}



1;

=pod

QAInfo::DataSource::EmailReports::MIMEParser - That is little wheel, that 
makes MIME parsing. Existing MIME-tools is very slow and MIME::Fast 
requires additional C resources.

Field "Date" will be automatically converted into ISO format

=cut
package QAInfo::DataSource::EmailReports::MIMEParser;
use HTTP::Date qw[ time2iso str2time ];

sub new {
    my ( $class, $msg ) = @_;
    my ( $date, $subject, $from, $to, $body);
    my $parsed_object = undef;
    if ( $msg =~ /^(.*?)\r?\n\r?\n(.+)/s ) {
        my $header = $1;
        my $body   = $2;

        $parsed_object = bless {}, $class;

        while ( $header =~ /^(\S+):\s(.+)$/mg) {
            $parsed_object->{$1} = $2;
        }
        $parsed_object->{body} = $body;
        if ( $parsed_object->{'Date'} ) {
            $parsed_object->{'Date'} = time2iso str2time($parsed_object->{'Date'});
        }
    }
    else {
        warn ("Can't extract header and body from message\n");
    }
    return $parsed_object;
}

sub get  { shift->{$_[0]} }
sub body { shift->{body}  }

# ============== Utils ======



1;